package com.ybear.ybutils.utils.notification;

import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.ybear.ybutils.utils.AppUtil;

import java.lang.ref.WeakReference;
import java.util.List;

public class NotificationX {
    private WeakReference<Context> mWrApp;
    private NotificationManager mNotifyManage;

    public static NotificationX get() { return NotificationX.HANDLER.INSTANCE; }
    private static final class HANDLER {
        private static final NotificationX INSTANCE = new NotificationX();
    }

    public void init(@NonNull Application app) {
        mWrApp = new WeakReference<>( app );
        mNotifyManage = (NotificationManager) app.getSystemService(
                Context.NOTIFICATION_SERVICE
        );
    }

    @Nullable
    private Context getContext() { return mWrApp.get(); }

    public NotificationManager getNotificationManager() { return mNotifyManage; }

    /**
     创建一个通知需要的Notification
     @param build       通知数据
     @return            {@link Notification}
     */
    @Nullable
    public Notification createNotification(NotificationBuild build) {
        Context context = getContext();
        if( context == null ) return null;
        if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
            addChannel( build.getChannel().getNotificationChannel() );
        }
        return build.build( context );
    }

    public boolean show(int id, Notification notification) {
        if( notification == null ) return false;
        try {
            getNotificationManager().notify( id, notification );
            return true;
        }catch(Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     展示一个通知
     @param id      通知id
     @param build   通知数据
     @return        展示结果
     */
    public boolean showNotification(int id, NotificationBuild build) {
        return show( id, createNotification( build ) );
    }

    /**
     展示一个通知
     @param id              通知id
     @param channelId       渠道id（8.0特性）
     @param channelName     渠道名（8.0特性）
     @param importance      通知重要性（8.0特性）
     @param smallIcon       小图标（通知左上角图标）
     @param largeIcon       大图标（内容右边的图标）
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param deleteIntent    取消/清空通知时的处理事件
     @param autoCancel      是否点击后自动取消
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    @NonNull String channelId,
                                    @Nullable String channelName,
                                    @Importance int importance,
                                    int smallIcon,
                                    int largeIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    @Nullable Intent deleteIntent,
                                    boolean autoCancel,
                                    boolean isShowBadge) {
        NotificationBuild build = new NotificationBuild(
                channelId, channelName, importance, isShowBadge
        );
        return showNotification( id, build
                .setSmallIcon( smallIcon )
                .setLargeIcon( largeIcon ).setTitle( title )
                .setContent( content )
                .setOpenIntent( openIntent )
                .setDeleteIntent( deleteIntent )
                .setAutoCancel( autoCancel )
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param smallIcon       小图标（通知左上角图标）
     @param largeIcon       大图标（内容右边的图标）
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param deleteIntent    取消/清空通知时的处理事件
     @param autoCancel      是否点击后自动取消
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    int smallIcon,
                                    int largeIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    @Nullable Intent deleteIntent,
                                    boolean autoCancel,
                                    boolean isShowBadge) {
        Context context = getContext();
        if( context == null ) return false;
        String channelId = AppUtil.getPackageName( context );
        return showNotification(
                id, channelId, null, Importance.UNSPECIFIED,
                smallIcon, largeIcon, title, content, openIntent, deleteIntent,
                autoCancel, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param smallIcon       小图标（通知左上角图标）
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param deleteIntent    取消/清空通知时的处理事件
     @param autoCancel      是否点击后自动取消
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    int smallIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    @Nullable Intent deleteIntent,
                                    boolean autoCancel,
                                    boolean isShowBadge) {
        return showNotification(
                id, smallIcon, -1, title, content, openIntent, deleteIntent,
                autoCancel, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param smallIcon       小图标（通知左上角图标）
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param deleteIntent    取消/清空通知时的处理事件
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    int smallIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    @Nullable Intent deleteIntent,
                                    boolean isShowBadge) {
        return showNotification(
                id, smallIcon, title, content, openIntent, deleteIntent, true, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param deleteIntent    取消/清空通知时的处理事件
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    @Nullable Intent deleteIntent,
                                    boolean isShowBadge) {
        return showNotification(
                id, -1, title, content, openIntent, deleteIntent, true, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param smallIcon       小图标（通知左上角图标）
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    int smallIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    boolean isShowBadge) {
        return showNotification(
                id, smallIcon, title, content, openIntent, null, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param title           标题
     @param content         内容
     @param openIntent      点击通知时的处理事件
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    @Nullable Intent openIntent,
                                    boolean isShowBadge) {
        return showNotification(
                id, -1, title, content, openIntent, null, isShowBadge
        );
    }

    /**
     展示一个通知
     @param id              通知id
     @param smallIcon       小图标（通知左上角图标）
     @param title           标题
     @param content         内容
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    int smallIcon,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    boolean isShowBadge) {
        return showNotification( id, smallIcon, title, content, null, isShowBadge );
    }

    /**
     展示一个通知
     @param id              通知id
     @param title           标题
     @param content         内容
     @param isShowBadge     是否展示桌面图标小圆点
     @return                展示结果
     */
    public boolean showNotification(int id,
                                    @Nullable CharSequence title,
                                    @Nullable CharSequence content,
                                    boolean isShowBadge) {
        return showNotification( id, -1, title, content, isShowBadge );
    }

    /**
     取消指定通知
     @param id      通知id
     */
    public void cancel(int id) { getNotificationManager().cancel( id ); }

    /**
     清空全部通知
     */
    public void cancelAll() { getNotificationManager().cancelAll(); }

    /**
     * 创建渠道组
     * @param channelId     渠道组id
     * @param channelName   渠道组名称
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationChannelGroup createChannelGroup(@NonNull String channelId,
                                                       @NonNull CharSequence channelName) {
        return new NotificationChannelGroup(channelId, channelName);
    }

    /**
     * 添加创建的渠道
     * @param group         渠道组{@link #createChannelGroup(String, CharSequence)}
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX addChannelGroup(NotificationChannelGroup group) {
        getNotificationManager().createNotificationChannelGroup( group );
        return this;
    }

    /**
     * 添加创建的渠道
     * @param groups        渠道组列表
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX addChannelGroups(List<NotificationChannelGroup> groups) {
        getNotificationManager().createNotificationChannelGroups( groups );
        return this;
    }

    /**
     * 删除渠道组
     * @param channelId     渠道id
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX deleteChannelGroup(String channelId) {
        getNotificationManager().deleteNotificationChannelGroup( channelId );
        return this;
    }

    /**
     * 创建渠道
     * @param channelId     渠道id
     * @param channelName   渠道名称
     * @param importance    重要性 {@link Importance}
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationChannel createChannel(@NonNull String channelId,
                                             @NonNull CharSequence channelName,
                                             @Importance int importance) {
        return new NotificationChannel( channelId, channelName, importance );
    }

    /**
     * 添加创建的渠道
     * @param channel       渠道{@link #createChannel(String, CharSequence, int)}
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX addChannel(NotificationChannel channel) {
        getNotificationManager().createNotificationChannel( channel );
        return this;
    }

    /**
     * 添加创建的渠道
     * @param channels       渠道列表
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX addChannels(List<NotificationChannel> channels) {
        getNotificationManager().createNotificationChannels( channels );
        return this;
    }

    /**
     * 删除渠道
     * @param channelId     渠道id
     * @return              this
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public NotificationX deleteChannel(String channelId) {
        getNotificationManager().deleteNotificationChannel( channelId );
        return this;
    }
}
